package com.imooc.controller;


import com.imooc.pojo.Users;
import com.imooc.pojo.bo.ShopcartBO;
import com.imooc.pojo.bo.UserBO;
import com.imooc.pojo.vo.UsersVO;
import com.imooc.service.UserService;
import com.imooc.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @author shkstart
 * @create 2022-03-06 17:05
 */
@Api(value="注册登录",tags = {"用于注册登录的相关接口"})
@RestController
@RequestMapping("passport")
public class PassportController extends BaseController{
    @Autowired
    private UserService userService;
    @Autowired
    private RedisOperator redisOperator;

    @ApiOperation(value="用户名是否存在",notes="用户名是否存在",httpMethod = "GET")
    @GetMapping("/usernameIsExist")
    public IMOOCJSONResult usernameIsExist(@RequestParam String username){
        //判断用户名不能为空
        if(StringUtils.isBlank(username)){
            return IMOOCJSONResult.errorMsg("用户名不能为空");
        }
        //查找注册的用户名是否存在
        boolean isExist=userService.queryUsernameIsExist(username);
        if(isExist){
            return IMOOCJSONResult.errorMsg("用户名已经存在");
        }
        //请求成功，没有重复
        return IMOOCJSONResult.ok();
    }

    @ApiOperation(value="用户注册",notes="用户注册",httpMethod = "POST")
    @PostMapping("/regist")
    public IMOOCJSONResult regist(@RequestBody UserBO userBO,
                                  HttpServletRequest request,
                                  HttpServletResponse response){
        String username=userBO.getUsername();
        String password=userBO.getPassword();
        String confirmPwd=userBO.getConfirmPassword();

        //判断用户名和密码必须不为空
        if(StringUtils.isBlank(username)||
                StringUtils.isBlank(password)||
                StringUtils.isBlank(confirmPwd)){
            return IMOOCJSONResult.errorMsg("用户名或密码不能为空");
        }
        //查询用户名是否存在
        boolean isExist=userService.queryUsernameIsExist(username);
        if(isExist){
            return IMOOCJSONResult.errorMsg("用户名已经存在");
        }
        //密码长度不能少于6位
        if(password.length()<6){
            return IMOOCJSONResult.errorMsg("密码长度不能少于6");
        }
        //判断两次密码是否一致
        if(!password.equals(confirmPwd)){
            return IMOOCJSONResult.errorMsg("两次密码输入不一致");
        }
        //实现注册
        Users userResult=userService.createUser(userBO);

        //清除一些私密信息，放置在cookie中
        //userResult=setNullProperty(userResult);

        //实现用户的redis会话
        //生成用户token，存入redis会话
        UsersVO usersVO = convertUserVO(userResult);

        //用户信息放入cookie
        CookieUtils.setCookie(request,response,"user",JsonUtils.objectToJson(usersVO),true);

        //同步购物车数据
        synchShopcartData(userResult.getId(),request,response);

        return IMOOCJSONResult.ok();
    }


    @ApiOperation(value="用户登录",notes="用户登录",httpMethod = "POST")
    @PostMapping("/login")
    public IMOOCJSONResult login(@RequestBody UserBO userBO
                                ,HttpServletRequest request
                                , HttpServletResponse response) throws Exception{
        String username=userBO.getUsername();
        String password=userBO.getPassword();

        //判断用户名和密码必须不为空
        if(StringUtils.isBlank(username)||
                StringUtils.isBlank(password)){
            return IMOOCJSONResult.errorMsg("用户名或密码不能为空");
        }
        //实现登录
        Users userResult=userService.queryUserForLogin(username, MD5Utils.getMD5Str(password));
        if(userResult==null)return IMOOCJSONResult.errorMsg("用户名或密码不正确");
        //userResult=setNullProperty(userResult);

        //实现用户的redis会话
        //生成用户token，存入redis会话
        UsersVO usersVO = convertUserVO(userResult);

        CookieUtils.setCookie(request,response,"user",JsonUtils.objectToJson(usersVO),true);
        //同步购物车数据
        synchShopcartData(userResult.getId(),request,response);

        return IMOOCJSONResult.ok(userResult);
    }

    /**
     * 注册登录成功后，同步cookie和redis中的购物车数据
     */
    private void synchShopcartData(String userId
                                    ,HttpServletRequest request
                                    , HttpServletResponse response){
        /**
         * redis中无数据，cookie购物车为空，不做任何处理
         *                cookie购物车不为空，此时cookie覆盖redis
         * redis中有数据，cookie购物车为空，直接把redis数据覆盖至cookie
         *               cookie购物车不为空，合并数据，以cookie中的为主，覆盖至redis（京东）
         * 同步后，要覆盖本地cookie
         */

        //从redis中获取购物车
        String shopcartJsonRedis=redisOperator.get(FOODIE_SHOPCART+":"+userId);

        //从cookie获取购物车
        String shopcartStrCookie=CookieUtils.getCookieValue(request,FOODIE_SHOPCART,true);

        if(StringUtils.isBlank(shopcartJsonRedis)){
            //redis为空，cookie不为空，此时cookie覆盖redis
            if(StringUtils.isNotBlank(shopcartStrCookie)){
                redisOperator.set(FOODIE_SHOPCART+":"+userId,shopcartStrCookie);
            }
        }else{
            //redis不为空，cookie不为空,合并数据，以cookie中的为主
            if(StringUtils.isNotBlank(shopcartStrCookie)){
                //1.对于两者都存在的商品，cookie数量覆盖redis（京东）
                //2.该商品标记为待删除放入list
                //3.从cookie中去除待删除的物品list，最后cookie中只剩下redis里没有的数据
                //4，合并redis和cookie
                //5.更新到redis和cookie中

                List<ShopcartBO> shopcartListRedis=JsonUtils.jsonToList(shopcartJsonRedis,ShopcartBO.class);
                List<ShopcartBO> shopcartListCookie=JsonUtils.jsonToList(shopcartStrCookie,ShopcartBO.class);
                List<ShopcartBO> pendingDeleteList=new ArrayList<>();//待删除list
                for(ShopcartBO redisShopcart:shopcartListRedis){
                    String redisSpecId=redisShopcart.getSpecId();

                    for(ShopcartBO cookieShopcart:shopcartListCookie){
                        String cookieSpecId=cookieShopcart.getSpecId();

                        if(redisSpecId.equals(cookieSpecId)){
                            //覆盖购买数量，以cookie为主，不累加
                            redisShopcart.setBuyCounts(cookieShopcart.getBuyCounts());
                            //把当前cookieShopcart放入待删除list，用于之后的删除与合拼
                            pendingDeleteList.add(cookieShopcart);
                        }
                    }
                }
                //从现有的cookie中删除待删除list，删除后cookie中只剩下redis里没有的数据
                shopcartListCookie.removeAll(pendingDeleteList);

                //合并两个list
                shopcartListRedis.addAll(shopcartListCookie);

                //更新到redis和cookie中
                redisOperator.set(FOODIE_SHOPCART+":"+userId,JsonUtils.objectToJson(shopcartListRedis));
                CookieUtils.setCookie(request,response,FOODIE_SHOPCART,JsonUtils.objectToJson(shopcartListRedis),true);


            }else{
                //redis不为空，cookie为空,redis覆盖cookie
                CookieUtils.setCookie(request,response,FOODIE_SHOPCART,shopcartJsonRedis,true);

            }
        }
    }

    @ApiOperation(value="用户退出登录",notes="用户退出登录",httpMethod = "POST")
    @PostMapping("/logout")
    public IMOOCJSONResult logout(@RequestParam String userId,
                                  HttpServletRequest request,
                                  HttpServletResponse response){
        //清除用户相关信息的cookie
        CookieUtils.deleteCookie(request,response,"user");
        //用户退出登录，需要清空cookie购物车
        CookieUtils.deleteCookie(request,response,FOODIE_SHOPCART);
        //分布式会话中需要清除redis用户数据
        redisOperator.del(REDIS_USER_TOKEN+":"+userId);

        return IMOOCJSONResult.ok();
    }

    private Users setNullProperty(Users userResult){
        userResult.setPassword(null);
        userResult.setMobile(null);
        userResult.setEmail(null);
        userResult.setCreatedTime(null);
        userResult.setUpdatedTime(null);
        userResult.setBirthday(null);
        return userResult;
    }
}
